package com.example.aspectj.aspect;

import android.util.Log;

import com.example.aspectj.annotation.ClickBehavior;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;

/**
 * 1.使用注解 @Aspect 来定义一个切面类。
 * 2.通过@Pointcut 寻找需要处理的切入点
 * 3.处理切入点
 */

@Aspect
public class ClickBehaviorAspect {

    private static final String TAG = ClickBehaviorAspect.class.getSimpleName();

    // 1. 应用中使用到了哪些注解，放到当前的切入点进行处理（找到需要处理的切入点）
    // execution 以方法执行时作为切点，触发Aspect类。 语法：execution()
    // * *(..) 通配符，可以处理ClickBehavior这个类所有的方法，也可以指定com.example.aspectj.MainActivity.login()方法作为切入点
    @Pointcut("execution(@com.example.aspectj.annotation.ClickBehavior * *(..))") //
    public void methodPointCut() {
    }

    //

    // 2. 对切入点如何处理，
    // Around 围绕切入点如何处理
    @Around("methodPointCut()")
    public Object jointPoint(ProceedingJoinPoint joinPoint) throws Throwable {
        // 遵循三个规则，返回值Object ， 参数ProceedingJoinPoint ， 抛出异常 Throwable

        // 获取签名方法
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        // 获取方法所属的类名
        String className = methodSignature.getDeclaringType().getSimpleName();
        // 获取方法名
        String methodName = methodSignature.getName();
        //获取方法的注解值（需要统计的行为），通过反射获取
        String funName = methodSignature.getMethod().getAnnotation(ClickBehavior.class).value();

        // 统计需求：统计方法执行的时间，统计用户点击某功能行为。（实际项目中，存储到本地，每隔*天上传到服务器）
        // 通过AspectJ在login()等方法执行前后插入代码，而不是通过Javac的方式。
        long begin = System.currentTimeMillis();
        Log.e(TAG, "ClickBehavior Method Start");
        Object result = joinPoint.proceed();// MainActivity中的切入点执行的方法
        Log.e(TAG, "ClickBehavior Method End");

        long duration = System.currentTimeMillis() - begin;
        Log.e(TAG, String.format("统计了：%s功能，在 %s类中执行了 %s 方法，用时 %d ms", funName, className, methodName, duration));
        return result;
    }
}
